/***
 * @Description:定义并实现链表功能，包括链表的增删改查和相关数据变量的定义的C语言文件
 * @Author: Liverpool
 * @Date: 2024-02-15 02:19:59
 * @LastEditTime: 2024-02-16 01:56:15
 * @LastEditors: Liverpool
 */
#include "list.h"
/***
 * @description: 链表结构初始化
 * @Author: Liverpool
 * @Date: 2024-02-16 01:59:21
 * @return {*}
 * @param {D_List} *list 需要进行初始化的链表地址
 */
void list_init(D_List *list)
{
    list->first = (D_ListNode *)0;
    list->last = (D_ListNode *)0;
    list->count = 0;
}

/***
 * @description: 在链表头部插入结点
 * @Author: Liverpool
 * @Date: 2024-02-16 22:39:35
 * @return {*}
 * @param {D_List} *list 需要插入的链表
 * @param {D_ListNode} *node 需要插入的结点
 */
void list_insert_first(D_List *list, D_ListNode *node)
{
    // 头部结点的前节点一定为空
    node->pre = (D_ListNode *)0;
    node->next = list->first; // 设置插入的结点的后结点为当前链表的首结点
    if (list_is_empty(list))
    {
        // 如果当前链表为空 需要头结点和尾结点都指向当前添加的结点
        list->first = node;
        list->last = node;
    }
    else
    {
        // 当前为非空链表
        list->first->pre = node; // 原头结点的前结点需要指向插入的结点
        list->first = node;      // 链表的头结点需要指向插入的结点
    }
    list->count++;
}

/***
 * @description: 在链表尾部部插入结点
 * @Author: Liverpool
 * @Date: 2024-02-16 22:39:35
 * @return {*}
 * @param {D_List} *list 需要插入的链表
 * @param {D_ListNode} *node 需要插入的结点
 */
void list_insert_last(D_List *list, D_ListNode *node)
{
    // 尾部结点的后节点一定为空
    node->pre = list->last; // 设置插入的结点的前结点为当前链表的尾结点
    node->next = (D_ListNode *)0;
    if (list_is_empty(list))
    {
        // 如果当前链表为空 需要头结点和尾结点都指向当前添加的结点
        list->first = node;
        list->last = node;
    }
    else
    {
        // 当前为非空链表
        list->last->next = node; // 原头结点的尾结点的后结点需要指向插入的结点
        list->last = node;       // 链表的尾结点需要指向插入的结点
    }
    list->count++;
}
/***
 * @description: 在链表中删除固定的结点
 * @Author: Liverpool
 * @Date: 2024-02-18 00:00:35
 * @return {*} 被删除的结点地址
 * @param {D_List} *list 需要删除的链表
 * @param {D_ListNode} *node 需要删除的结点
 */
D_ListNode *list_remove_node(D_List *list, D_ListNode *node)
{
    // 1.首先判断删除的结点是否为链表的头尾结点
    if (node == list->first)
    {
        list->first = node->next; // 如果删除的结点为链表头结点 那么头结点需要指向删除结点的next指针
    }
    if (list->last == node)
    {
        list->last = node->pre; // 如果删除的结点为链表的尾结点 那么尾结点需要指向删除结点的pre指针
    }
    if (node->pre) // 如果拥有前结点
    {
        node->pre->next = node->next; // 前节点的next指针需要指向被删除结点的next指针
    }
    if (node->next) // 拥有后结点
    {
        node->next->pre = node->pre; // 后结点的pre指针需要指向被删除结点的pre指针
    }
    // 删除结点
    node->pre = node->next = (D_ListNode *)0;
    list->count--; // 链表的计数递减
    return node;
}

/***
 * @description: 在指定结点后插入新结点
 * @Author: Liverpool
 * @Date: 2024-02-18 23:06:27
 * @return {*}
 * @param {D_List} *list 要插入的链表
 * @param {D_ListNode} *pre 指定的结点
 * @param {D_ListNode} *node 需要插入的新结点
 */
void list_insert_after(D_List *list, D_ListNode *pre, D_ListNode *node)
{
    if (list_is_empty(list) || !pre) // 当前链表为空或者前结点为空的时候就直接在链表的头结点位置处插入
    {
        list_insert_first(list, node);
        return;
    }

    node->next = pre->next; // 插入新结点的后指针指向前结点的next
    node->pre = pre;        // 插入新结点的前指针指向前结点
    if (pre->next)
    {
        pre->next->pre = node; // 原来前结点的后节点的pre指针需要指向新插入的结点
    }
    pre->next = node; // 更新前结点的next指针
    if (list->last == pre)
    {
        list->last = node; // 如果链表的尾结点为之前的pre结点那就需要更新为新插入的结点
    }
    list->count++;
}